#include "card.h"
//#include "ccid.h"

#include "main.h"

Card_t Card;

//#define VERBOSE_TYPE
#define VERBOSE_ATR

/*
 * PC/SC 3.1.3.2.3 (pcsc3_v2.01.09.pdf):
 * For contactless ICCs, the IFD subsystem must construct an ATR from the fixed elements that identify the cards.
 * ATS for JCOP and other 14443-4-compatible: file 14443-4.pdf, page 6
 */
void Card_t::ConfigATR(uint8_t* PBuf, uint16_t Length) {
    // PBuf - Buf recieved from PN: payload data started from PBuf[3]
    uint8_t* PBufElement = &PBuf[3];
    DataLength = Length-3;
    ClearATR();
//    klPrintf("ATR: %A\r", PBuf, Length);
    // Define Card type
    if(PBufElement[0] & 0x50){ // type B (Inifneon)
        Type = ctInfineon;
        uint8_t ATQBLengh = 12;
        ATR_Length = 17;
        uint8_t HistoricalBytesLength = 0x0C;// Next byte after T0 (TA1 or TB1 or TC1 or HistoricalByte (12 bytes length anytime)
        ATR_Buf[0] = 0x3B;  // Initial
        ATR_Buf[1] = 0x80 | HistoricalBytesLength; // T0: Higher nibble 8 means no TA1, TB1, TC1 only TD1 is following. Lower nibble is the number of historical bytes
        ATR_Buf[2] = 0x80;  // TD1: Higher nibble 8 means no TA2, TB2, TC2 only TD2 is following. Lower nibble 0 means T = 0
        ATR_Buf[3] = 0x01;  // TD2: Higher nibble 0 means no TA3, TB3, TC3, TD3 following. Lower nibble 1 means T = 1
        memcpy(&ATR_Buf[4], PBufElement, ATQBLengh);
        // TCK
        uint8_t TCK=0;
        TCK ^= ATQBLengh;
        for (uint8_t i=3; i<ATR_Length-1; i++) TCK ^= ATR_Buf[i];    // Exclusive-OR of bytes T0 to Tk
        ATR_Buf[ATR_Length-1] = TCK;
    }

    else if(PBufElement[2] & 0x20){ // type A (jCop)
        Type = ctJCop;
        //klPrintf("SensRes: %X %X; SelRes: %X\r", Data[0], Data[1], Data[2]);
        uint8_t NFCIDLength = PBufElement[3];
        uint8_t ATSLength = 0;
//            klPrintf("NFCIDLength: %X\r", NFCIDLength);
//            klPrintf("NFCID: %A\r", &Buf[4], NFCIDLength);
        uint8_t *ATS = &PBufElement[4+NFCIDLength];    // TL
        ATSLength = *ATS++;                     // Get length and move to first byte of ATS (T0)
//            klPrintf("ATSLength: %X\r", ATSLength);
        uint8_t HistoricalBytesLength = 0, *HistoricalBytes = ATS+1;    // Next byte after T0 (TA1 or TB1 or TC1 or HistoricalByte)
        if (ATSLength > 1) {    // There are something else besides mandatory TL byte
            //klPrintf("ATS: %A\r", ATS, ATSLength-1);
            uint8_t T0 = ATS[0];
            // The least significant half byte b4 to b1 is called FSCI and codes FSC. The FSC defines the maximum size of a frame accepted by the PICC.
            HistoricalBytesLength = ATSLength - 1 - 1;  // -Length -T0
            if (T0 & 0x10) {    // TA1 exist
                HistoricalBytesLength--;
                HistoricalBytes++;
            }
            if (T0 & 0x20) {    // TB1 exist
                HistoricalBytesLength--;
                HistoricalBytes++;
            }
            if (T0 & 0x40) {    // TC1 exist
                HistoricalBytesLength--;
                HistoricalBytes++;
            }
            //klPrintf("HistoricalBytesLength: %u; HistoricalBytes: %A\r", HistoricalBytesLength, HistoricalBytes, HistoricalBytesLength);
        }

        ATR_Buf[0] = 0x3B;  // Initial
        ATR_Buf[1] = 0x80 | HistoricalBytesLength; // T0: Higher nibble 8 means no TA1, TB1, TC1 only TD1 is following. Lower nibble is the number of historical bytes
        ATR_Buf[2] = 0x80;  // TD1: Higher nibble 8 means no TA2, TB2, TC2 only TD2 is following. Lower nibble 0 means T = 0
        ATR_Buf[3] = 0x01;  // TD2: Higher nibble 0 means no TA3, TB3, TC3, TD3 following. Lower nibble 1 means T = 1
        // Historical bytes from ATS response
        if (HistoricalBytesLength > 0) {
            memcpy(&ATR_Buf[4], HistoricalBytes, HistoricalBytesLength);
            ATR_Length = 4 + HistoricalBytesLength + 1;  // 4 mandatory bytes + historical bytes + TCK
        }
        else ATR_Length = 5;
    }

    else{ // Type A (Mifare)
        Type = ctMifare;
        uint8_t SAK = PBufElement[2];
        uint8_t ATQA1 = PBufElement[0], ATQA2 = PBufElement[1];
        ATR_Length = 20;
        ATR_Buf[0] = 0x3B;  // Initial
        ATR_Buf[1] = 0x8F;  // T0: Higher nibble 8 means no TA1, TB1, TC1 only TD1 is following. Lower nibble is the number of historical bytes
        ATR_Buf[2] = 0x80;  // TD1: Higher nibble 8 means no TA2, TB2, TC2 only TD2 is following. Lower nibble 0 means T = 0
        ATR_Buf[3] = 0x01;  // TD2: Higher nibble 0 means no TA3, TB3, TC3, TD3 following. Lower nibble 1 means T = 1
        // Historical bytes
        ATR_Buf[4] = 0x80;  // T1: Category indicator byte, 80 means A status indicator may be present in an optional COMPACT-TLV data object
        ATR_Buf[5] = 0x4F;  // Application identifier Presence indicator
        ATR_Buf[6] = 0x0C;  // Length
        // 5 bytes: Registered application provider identifier (RID); pcsc3_v2.01.08_sup.pdf
        // The PC/SC Workgroup has its own 5-byte RID. The specification mandates to use this RID for compliant IFD subsystems.
        ATR_Buf[7] = 0xA0;
        ATR_Buf[8] = 0x00;
        ATR_Buf[9] = 0x00;
        ATR_Buf[10] = 0x03;
        ATR_Buf[11] = 0x06;
        // *** PIX (7 bytes max) ***
        ATR_Buf[12] = 0x03; // SS: Byte for standard; here ISO 14443 A, part 3
        // The two bytes for Card Name represent a number which will be assigned by the PC/SC Workgroup upon request
        ATR_Buf[13] = 0x00; ATR_Buf[14] = 0x00;     // No information given
        if      ((ATQA1 == 0x00) and (ATQA2 == 0x04) and (SAK == 0x09)) { ATR_Buf[13] = 0x00; ATR_Buf[14] = 0x26; } // MifareMini
        else if ((ATQA1 == 0x00) and (ATQA2 == 0x04) and (SAK == 0x08)) { ATR_Buf[13] = 0x00; ATR_Buf[14] = 0x01; } // MifareClassic1K
        else if ((ATQA1 == 0x00) and (ATQA2 == 0x02) and (SAK == 0x18)) { ATR_Buf[13] = 0x00; ATR_Buf[14] = 0x02; } // MifareClassic4K
        else if ((ATQA1 == 0x00) and (ATQA2 == 0x44) and (SAK == 0x00)) { ATR_Buf[13] = 0x00; ATR_Buf[14] = 0x03; } // MifareUltralight
        // RFU: shall be set to zero
        ATR_Buf[15] = 0x00;
        ATR_Buf[16] = 0x00;
        ATR_Buf[17] = 0x00;
        ATR_Buf[18] = 0x00;
    }

    // TCK
    uint8_t TCK=0;
    for (uint8_t i=1; i<ATR_Length-1; i++) TCK ^= ATR_Buf[i];    // Exclusive-OR of bytes T0 to Tk
    ATR_Buf[ATR_Length-1] = TCK;

#ifdef VERBOSE_ATR
    Uart.Printf("ATR: %A\r", ATR_Buf, ATR_Length);
#endif
}
/*
void Card_t::DetermineType(void) {
    // Get ATQA and SAK from target data
    uint8_t ATQA1 = Data[0], ATQA2 = Data[1], SAK = Data[2];
    if      ((ATQA1 == 0x00) and (ATQA2 == 0x04) and (SAK == 0x09)) Type = ctMifareMini;
    else if ((ATQA1 == 0x00) and (ATQA2 == 0x04) and (SAK == 0x08)) Type = ctMifareClassic1K;
    else if ((ATQA1 == 0x00) and (ATQA2 == 0x02) and (SAK == 0x18)) Type = ctMifareClassic4K;
    else if ((ATQA1 == 0x00) and (ATQA2 == 0x44) and (SAK == 0x00)) Type = ctMifareUltralight;
    else if ((ATQA1 == 0x03) and (ATQA2 == 0x44) and (SAK == 0x20)) Type = ctMifareDESFire;
    else if ((ATQA1 == 0x00) and (ATQA2 == 0x04) and (SAK == 0x88)) Type = ctInfineonMifareClassic1K;

    else if (
            ((ATQA1 == 0x03) and (ATQA2 == 0x04) and (SAK == 0x28)) or
            ((ATQA1 == 0x00) and (ATQA2 == 0x48) and (SAK == 0x20)) or
            ((ATQA1 == 0x00) and (ATQA2 == 0x04) and (SAK == 0x28))
            )
            Type = ctJCOP;

#ifdef VERBOSE_TYPE
    switch (Type) {
        case ctUndefined:        klPrintf("Undefined\r"); break;
        case ctMifareMini:       klPrintf("MifareMini\r"); break;
        case ctMifareClassic1K:  klPrintf("MifareClassic1K\r"); break;
        case ctMifareClassic4K:  klPrintf("MifareClassic4K\r"); break;
        case ctMifareUltralight: klPrintf("MifareUltralight\r"); break;
        case ctMifareDESFire:    klPrintf("MifareDESFire\r"); break;
        case ctInfineonMifareClassic1K: klPrintf("InfineonMifareClassic1K\r"); break;
        case ctJCOP:             klPrintf("JCOP\r"); break;
    }
#endif
}
*/

